<template>
  <div class="upload-file">
    <el-upload
      :http-request="uploadRequest"
      :action="uploadFileUrl"
      multiple
      :before-upload="handleBeforeUpload"
      :file-list="fileList"
      :limit="limit"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :headers="headers"
      :on-change="handleChange"
      class="upload-file-uploader"
      ref="upload"
      :auto-upload="true"
      :data="{ siteAlias: siteRow.alias || null, fileType: fileTypeParams }"
    >
      <!-- 上传按钮  选取文件 -->
      <el-button slot="trigger" size="small" type="primary">上传文件</el-button>
      <el-button
        style="margin-left: 10px"
        size="small"
        type="success"
        @click="submitUpload"
        v-if="false"
        >上传文件</el-button
      >
      <!-- 上传提示 -->
      <div class="el-upload__tip" slot="tip" v-if="showTip">
        请上传
        <template v-if="fileSize">
          大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template
        ><br />
        <template v-if="fileType">
          格式为 <b style="color: #f56c6c">{{ fileType.join(" , ") }}</b>
        </template>
        的文件
      </div>
    </el-upload>

    <!-- 当前上传  文件列表  fileList   -->
    <transition-group
      class="upload-file-list el-upload-list el-upload-list--text drag-ul"
      name="el-fade-in-linear"
      tag="ul"
      ref="file_list_ul"
    >
      <!-- <li :key="index" class="el-upload-list__item ele-upload-list__item-content" v-for=" (file, index)  in fileList" @mouseenter="uid = file.uid||file.id" @mouseleave="uid = null"> -->
      <li
        :key="file.uid"
        class="el-upload-list__item ele-upload-list__item-content"
        v-for="(file, index) in uploadList"
        @mouseenter="uid = file.uid || file.id"
        @mouseleave="uid = null"
      >
        <!-- <el-link :href="`${file.storeName}`" :underline="false" target="_blank"> -->
        <span
          class="file-icon"
          @click="getFileUrl(file)"
          :style="{
            'background-position-y':
              getFileIconY(file.realName || file.name) + 'px',
          }"
        >
          {{ file.realName || file.name }}
        </span>
        <!-- </el-link> -->
        <!-- <span style="width: 100px;">
          <el-input v-model="file.sequence" placeholder="请输入内容"></el-input>
        </span> -->

        <span style="width: 100px; text-align: center">
          {{ conver(file.size) }}
        </span>
        <span>
          {{ file.sequence }}
        </span>
        <span>
          <el-button
            icon="el-icon-top"
            size="small"
            @click="handleFileSeqUp(file, index, $event)"
          ></el-button>
          <el-button
            icon="el-icon-bottom"
            size="small"
            @click="handleFileSeqDown(file, index, $event)"
          ></el-button>
        </span>
        <div
          class="ele-upload-list__item-content-action"
          v-if="file.status == 'success' && uid != file.uid"
        >
          <el-link
            :underline="false"
            :type="file.response.code == 200 ? 'success' : 'danger'"
          >
            {{ file.response.code == 200 ? "上传成功" : "上传失败" }}
          </el-link>
        </div>

        <div
          class="ele-upload-list__item-content-action"
          v-else-if="file.status == 'ready' && uid != file.uid"
        >
          <el-link :underline="false" type="primary">准备上传 </el-link>
        </div>
        <div
          class="ele-upload-list__item-content-action"
          v-else-if="file.status == 'uploading' && uid != file.uid"
        >
          <el-link :underline="false" type="warning">正在上传 </el-link>
        </div>
        <!-- 不要乱动文件删除 -->
        <div class="ele-upload-list__item-content-action">
          <el-link
            :underline="false"
            @click="handleDelete(file, index)"
            type="danger"
            >删除
          </el-link>
        </div>
      </li>
    </transition-group>

    <h1>已上传附件</h1>

    <!-- 历史文件 文件列表 -->
    <transition-group
      class="upload-file-list el-upload-list el-upload-list--text"
      name="el-fade-in-linear"
      tag="ul"
    >
      <li
        :key="file.id"
        class="el-upload-list__item ele-upload-list__item-content"
        v-for="(file, index) in historyAttr"
        @mouseenter="uid = file.id"
        @mouseleave="uid = null"
      >
        <!-- <el-link :href="`${file.storeName}`" :underline="false" target="_blank"> -->
        <span
          class="file-icon"
          :style="{
            'background-position-y':
              getFileIconY(file.realName || file.name) + 'px',
          }"
          @click="getFileUrl(file)"
        >
          {{ file.realName || file.name }}
        </span>
        <!-- </el-link> -->
        <span> 历史文件 </span>
        <span v-if="false">
          <el-button
            icon="el-icon-top"
            size="small"
            @click="handleFileSeqUp(file, index, $event)"
          ></el-button>
          <el-button
            icon="el-icon-bottom"
            size="small"
            @click="handleFileSeqDown(file, index, $event)"
          ></el-button>
        </span>

        <!-- 不要乱动文件删除 -->
        <div class="ele-upload-list__item-content-action">
          <el-link
            :underline="false"
            @click="handleDelete(file, index)"
            type="danger"
            >删除
          </el-link>
        </div>
      </li>
    </transition-group>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";
import { mapState } from "vuex";
import Sortable from "sortablejs";

export default {
  name: "FileUpload",
  props: {
    fileTypeParams: {
      type: String,
      default: "docs",
    },
    // 值
    value: [String, Object, Array],
    // 数量限制
    limit: {
      type: Number,
      default: 20,
    },
    // 大小限制(MB)
    fileSize: {
      type: Number,
      default: 5,
    },
    // 文件类型, 例如['png', 'jpg', 'jpeg']
    fileType: {
      type: Array,
      default: () => ["doc", "xls", "ppt", "txt", "pdf"],
    },
    // 是否显示提示
    isShowTip: {
      type: Boolean,
      default: true,
    },
    historyAttr: {},
  },
  data() {
    return {
      number: 0,
      successNum: 0,
      uploadList: [],
      baseUrl: process.env.VUE_APP_BASE_API,
      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
      headers: {
        Authorization: getToken(),
      },
      fileList: [],
      uid: null,
    };
  },
  watch: {
    value: {
      handler(val) {
        if (val) {
          let temp = 1;
          // 首先将值转为数组
          const list = Array.isArray(val) ? val : this.value.split(",");
          // 然后将数组转为对象数组
          this.fileList = list.map((item) => {
            if (typeof item === "string") {
              item = { realName: item, storeName: item };
            }
            item.uid = item.uid || new Date().getTime() + temp++;
            item.id = item.uid || new Date().getTime() + temp++;
            return item;
          });
        } else {
          this.fileList = [];
          return [];
        }
      },
      deep: true,
      immediate: true,
    },
  },
  computed: {
    // 是否显示提示
    showTip() {
      return this.isShowTip && (this.fileType || this.fileSize);
    },
    ...mapState({
      siteRow: (state) => state.column.siteRow,
    }),
    allList() {
      let arr = this.historyAttr.concat(this.fileList).map((item) => {
        item.idd = item.id || item.uid;
        return item;
      });
      console.log("arr: ", arr);
      return arr;
    },
  },
  mounted() {
    // this.$nextTick(() => {
    //   this.init();
    // });
  },
  methods: {
    submitUpload() {
      console.log("this.fileList: ", this.fileList);
      this.$refs.upload.submit();
    },
    //
    /**
     * 上传前校检格式和大小   这个是真实上传时才执行的/
     * 在change中判断了。选取文件就先判断了
     */
    handleBeforeUpload(file) {
      console.log("handleBeforeUpload", file);
      // 校检文件类型
      if (this.fileType) {
        let fileExtension = "";
        if (file.name.lastIndexOf(".") > -1) {
          fileExtension = file.name
            .slice(file.name.lastIndexOf(".") + 1)
            .toLocaleLowerCase();
        }
        console.log("fileExtension: ", fileExtension);

        const isTypeOk = this.fileType.some((type) => {
          if (file.type.indexOf(type) > -1) return true;
          if (fileExtension && fileExtension == type) return true;
          return false;
        });
        console.log("isTypeOk: ", isTypeOk);

        if (!isTypeOk) {
          this.$message.error(
            `文件格式不正确, 请上传${this.fileType.join(" ， ")}格式文件!`
          );
          return false;
        }
      }
      // 校检文件大小
      if (this.fileSize) {
        const isLt = file.size / 1024 / 1024 < this.fileSize;
        if (!isLt) {
          this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
          return false;
        }
      }
      console.log("handleBeforeUpload 正在上传文件，请稍候...");
      this.number++;
      console.log("this.number: ", this.number);
      return true;
    },
    // 文件个数超出
    handleExceed() {
      this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
    },
    handleChange(file, fileList) {
      console.log(
        "🚀 ~ file: index.vue ~ line 220 ~ handleChange ~ file",
        file
      );
      this.fileList = fileList;
      // 校检文件类型
      if (this.fileType) {
        console.log("this.fileType: ", this.fileType);
        let fileExtension = "";
        if (file.name.lastIndexOf(".") > -1) {
          fileExtension = file.name
            .slice(file.name.lastIndexOf(".") + 1)
            .toLocaleLowerCase();
        }
        const isTypeOk = this.fileType.some((type) => {
          console.log("type: ", type);
          if (file.type?.indexOf(type) > -1) return true;
          if (fileExtension && fileExtension == type) return true;
          return false;
        });
        console.log("isTypeOk: ", isTypeOk);

        const currIdx = this.fileList.indexOf(file);
        if (!isTypeOk) {
          this.$confirm(
            `<span style='color:red'> ${
              file.name
            }</span> 文件格式不正确, 请上传${this.fileType.join(
              " ， "
            )}格式文件!`,
            "提示",
            {
              confirmButtonText: "确定",

              dangerouslyUseHTMLString: true,
              type: "warning",
            }
          )
            .then(() => {})
            .catch(() => {
              return;
            });
          this.fileList.splice(currIdx, 1);
          return false;
        }
        // 校检文件大小
        if (this.fileSize) {
          const isLt = file.size / 1024 / 1024 < this.fileSize;
          if (!isLt) {
            // this.$message.error();
            this.$confirm(
              `<span style='color:red'> ${file.name}</span>文件大小不能超过 ${this.fileSize} MB!`,
              "提示",
              {
                confirmButtonText: "确定",

                dangerouslyUseHTMLString: true,
                type: "warning",
              }
            )
              .then(() => {})
              .catch(() => {
                return;
              });
            this.fileList.splice(currIdx, 1);
            return false;
          }
        }
      }

      console.log("this.fileList: ", this.fileList);
    },
    // 上传失败
    handleUploadError(err) {
      this.$message.error("上传失败, 请重试");
    },
    // 上传成功回调
    handleUploadSuccess(res, file) {
      console.log("handleUploadSuccess res, file: ", res, file);
      if (res.code != 200) {
        this.number--;
        this.msgError(file.name + "上传失败, 请移除文件后重新上传");
        return;
      }
      this.successNum++;
      this.uploadList.push({
        code: res.code,
        realName: res.realName || file.name,
        url: res.url,
        storeName: res.storeName,
        sequence: this.number + this.historyAttr.length - this.successNum,
        uid: file.uid,
        size: file.size,
      });
      console.log(
        "this.uploadList.length === this.number: ",
        this.uploadList,
        this.uploadList.length,

        this.number
      );
      console.log("this.fileList : ", this.fileList);

      if (this.uploadList.length === this.number) {
        // this.fileList = this.uploadList;
        this.$emit("input", JSON.stringify(this.uploadList));
        // this.uploadList = [];
        // this.number = 0;
      }

      // if (res.code == 200) {
      //   this.$message.success("上传成功");
      //   this.$emit("input", JSON.stringify(this.fileList));
      // } else {
      //   this.$message.error("上传失败");
      // }

      // this.fileList.push({
      //   realName: res.realName,
      //   url: res.url,
      //   storeName: res.storeName,
      // });
    },
    // 删除文件
    // <!-- 不要乱动文件删除 -->
    handleDelete(file, index) {
      console.log("file: ", file);
      // let i = this.fileList.findIndex((item) => {
      //   return (item.name = file.name);
      // });
      let namme = file.name || file.realName;
      this.$confirm('是否确认删除文件 " ' + namme + " ? ", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          if (file.articleId && file.id) {
            console.log("file: ", file);
            let ids = file.id;
            this.$emit("delete", ids, index);
            console.log("file: ", file);
          } else {
            this.$emit("deleteNewFile", index);
            this.fileList.splice(index, 1);
          }

          // return;

          // if (file.status == "success" && file.id) {
          //   let ids = file.storeName || file.response.storeName;
          //   this.$emit("delete", ids, index);
          // } else {
          //   this.fileList.splice(index, 1);
          // }
        })

        .catch(() => {});
    },
    /**
     * 文件排序上升
     */
    handleFileSeqUp(file, index, e) {
      console.log("file, index, e: ", file, index, e);
      const list = this.$refs.file_list_ul.$el;
      console.log("list: ", list);
      // file.sequence = index;
      const item = e.target.closest("li"); // 获取要移动的元素
      const prev = item.previousElementSibling;
      if (prev) {
        list.insertBefore(item, prev);
      }

      this.$nextTick(() => {
        this.uploadList = this.swapAdjacentElements(
          this.uploadList,
          index,
          "up"
        );
        this.uploadList.map((item, i) => {
          item.sequence = this.number - i - 1;
          return item;
        });
        console.log("this.uploadList: ", this.uploadList);

        this.$emit("input", JSON.stringify(this.uploadList));
      });
    },
    /**
     * 文件排序下降
     */
    handleFileSeqDown(file, index, e) {
      console.log("file, index, e: ", file, index, e);
      const list = this.$refs.file_list_ul.$el;
      // file.sequence = index - 1;
      console.log("list: ", list);
      const item = e.target.closest("li"); // 获取要移动的元素
      const next = item.nextElementSibling;
      if (next) {
        list.insertBefore(next, item);
      }
      this.$nextTick(() => {
        this.uploadList = this.swapAdjacentElements(
          this.uploadList,
          index,
          "down"
        );
        this.uploadList.map((item, i) => {
          item.sequence = this.number - i - 1;
          return item;
        });
        console.log("this.uploadList: ", this.uploadList);
        this.$emit("input", JSON.stringify(this.uploadList));
      });
    },
    /**
     * 相邻2个元素交换位置
     */
    swapAdjacentElements(array, index, t) {
      const temp = array[index];
      array[index] = t == "up" ? array[index - 1] : array[index + 1];
      if (t == "up") {
        array[index - 1] = temp;
      } else {
        array[index + 1] = temp;
      }
      console.log("array: ", array);
      return array;
    },
    //计算文件大小
    conver(limit) {
      if (!limit) return;
      var size = "";
      if (limit < 0.1 * 1024) {
        //如果小于0.1KB转化成B
        size = limit.toFixed(2) + "B";
      } else if (limit < 0.1 * 1024 * 1024) {
        //如果小于0.1MB转化成KB
        size = (limit / 1024).toFixed(2) + "KB";
      } else if (limit < 0.1 * 1024 * 1024 * 1024) {
        //如果小于0.1GB转化成MB
        size = (limit / (1024 * 1024)).toFixed(2) + "MB";
      } else {
        //其他转化成GB
        size = (limit / (1024 * 1024 * 1024)).toFixed(2) + "GB";
      }

      var sizestr = size + "";
      var len = sizestr.indexOf(".");
      var dec = sizestr.substr(len + 1, 2);
      if (dec == "00") {
        //当小数点后为00时 去掉小数部分
        return sizestr.substring(0, len) + sizestr.substr(len + 3, 2);
      }
      return sizestr;
    },
    getFileUrl(file) {
      this.$emit("getFileUrl", file);
    },
    getFileIconY(fileName) {
      let y = 0;
      if (!fileName && fileName.indexOf(".") > -1) return y;
      let expandName = fileName.split(".")[1].toLocaleLowerCase();
      switch (expandName) {
        case "doc":
          y = -32;
          break;
        case "docx":
          y = -64;
          break;
        case "dot":
          y = -96;
          break;
        case "rtf":
          y = -128;
          break;
        case "xlsx":
          y = -160;
          break;
        case "xls":
          y = -192;
          break;
        case "xlt":
          y = -224;
          break;
        case "ett":
          y = -256;
          break;
        case "et":
          y = -288;
          break;
        case "pptx":
          y = -320;
          break;
        case "ppt":
          y = -352;
          break;
        case "pps":
          y = -384;
          break;
        case "pot":
          y = -416;
          break;
        case "pdf":
          y = -448;
          break;
        case "wps":
          y = -480;
          break;
        case "wpt":
          y = -512;
          break;
        case "dps":
          y = -544;
          break;
        case "dpt":
          y = -576;
          break;
        case "zip":
          y = -608;
          break;
        case "rar":
          y = -640;
          break;
        case "txt":
          y = -672;
          break;
        case "ceb":
          y = -704;
          break;

        default:
          break;
      }
      return y;
    },
    init() {
      const dragUl = document.querySelector(".drag-ul");
      Sortable.create(dragUl, {
        animation: 1500,

        // 元素被选中
        onChoose: (/**Event*/ evt) => {},

        // 开始拖拽的时候
        onStart: (/**Event*/ evt) => {},

        // 结束拖拽
        onEnd: (/**Event*/ evt) => {
          let { newIndex, oldIndex } = evt;
          this.fileList[oldIndex].sequence = newIndex;
        },
      });
    },
  },
};
</script>

<style scoped lang="scss">
.upload-file-uploader {
  margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
  height: 40px;
  border: 1px solid #e4e7ed;
  line-height: 2;
  margin-bottom: 6px;
  position: relative;
}
.upload-file-list .ele-upload-list__item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: inherit;
}
.ele-upload-list__item-content-action {
  width: 80px;
  text-align: center;
  .el-link {
    margin-right: 10px;
  }
}

.file-icon {
  min-width: 300px;
  width: 60%;
  background-image: url("~@/assets/images/file.png");
  background-repeat: no-repeat;
  background-position-x: 0px;
  background-position-y: 0px;
  height: 32px;
  line-height: 34px;
  padding-left: 36px;
}
</style>
